package com.springmvc.init.handlerAdapter;

import com.alibaba.fastjson.JSON;
import com.springmvc.annotation.RequestParam;
import com.springmvc.annotation.ResponseBody;
import com.springmvc.init.handlerMapping.RequestMethodInfo;
import org.springframework.stereotype.Component;

import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.Map;

@Component
public class AnnotationHandlerAdapter implements HandlerAdapter {
    @Override
    public boolean isSuuport(Object object) {
        return object instanceof RequestMethodInfo;
    }

    @Override
    public Object handler(HttpServletRequest request, HttpServletResponse response, Object handler) {
        if (handler == null || !(handler instanceof RequestMethodInfo)) {
            return null;
        }
        RequestMethodInfo methodInfo = (RequestMethodInfo) handler;
        Method method = methodInfo.getMethod();
        Object target = methodInfo.getTarget();

        Parameter[] targetPameters = method.getParameters();
        Map<String, String[]> paramMap = request.getParameterMap();//请求携带的参数
        Object[] argument = new Object[method.getParameterCount()];
        for (int i = 0; i < targetPameters.length; i++) {
            Parameter parameter = targetPameters[i];
            String parName = parameter.getName();
            for (Map.Entry<String, String[]> entry : paramMap.entrySet()) {
                if (parameter.isAnnotationPresent(RequestParam.class)) {
                    if (parameter.getAnnotation(RequestParam.class).value().equals(entry.getKey())) {
                        argument[i] = entry.getValue()[0];
                    }
                } else if (parName.equals(entry.getKey())) {
                    argument[i] = entry.getValue()[0];
                }

                if (ServletRequest.class.isAssignableFrom(parameter.getType())) {
                    argument[i] = request;
                }
                if (ServletResponse.class.isAssignableFrom(parameter.getType())) {
                    argument[i] = response;
                }
            }
        }
        try {
            Object result = method.invoke(target, argument);
            if (result instanceof String) {
                if ("forward".equals(((String) result).split(":")[0])) {
                    request.getRequestDispatcher(((String) result).split(":")[1]).forward(request, response);
                } else {
                   return result;
                }
            }
            if (method.isAnnotationPresent(ResponseBody.class)) {
                return JSON.toJSONString(result);
            }
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (ServletException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

return  null;
    }
}
